<?php
/**
 * app端返回屏保图片列表
 * Author: lyun
 * Date: 2018/6/20
 * Created by Panxsoft.
 */


namespace App\Http\Controllers\App;

use App\Http\Controllers\ApiController;
use App\Models\Customer\Banner;
use App\Services\Utils\Guard;
use Illuminate\Database\Eloquent\Builder;

class BannerController extends ApiController
{
    const ROUTES = [
        'index' => 'api.app.banner.index'
    ];

    /**
     * app端返回屏保图片列表
     * @test
     *
     * @return array|\Illuminate\Http\Response
     */
    public function index()
    {
        $device_account = Guard::deviceAccount();
        $customer = $device_account->customer;
        $store_id = $device_account->store->id ?? null;

        /**
         * @see indexQueryExampleLog()
         */
        $banners = (new Banner)
            ->where('customer_id', $customer->id)
            ->filterDeviceAccountId($device_account->id)
            ->filterLimitDate()
            ->orWhere($this->filterStoreId($store_id))
            ->orderBy('priority', 'DESC')
            ->with('bannerType')
            ->get();

        if ($customer->showPanxBanner()) {
            // insert panx's adverts
            $panx_banners =  (new Banner)
                ->where('customer_id', Banner::CUSTOMER_ID_PANX)
                ->filterLimitDate()
                ->orderBy('priority', 'DESC')
                ->with('bannerType')
                ->get();

            // panx in the front
            $banners = $panx_banners->merge($banners);
        }

        return $this->response(compact('banners'));
    }

    /**
     * @param $store_id
     * @return \Closure
     */
    private function filterStoreId($store_id): \Closure
    {
        /**
         * @param Builder|Banner $query
         */
        return function (Builder $query) use ($store_id) {
            $query->filterStoreId($store_id);
        };
    }

    /**
     * index 查询使用了两个 exist + 表连接
     */
    final private function indexQueryExampleLog()
    {
        $query = <<<LOG
            -- noinspection SqlDialectInspection
            
            select *
            from `banners`
            where `customer_id` = 1
            and 
            exists ( 
                select *
                from `device_accounts`
                inner join `bannerables` 
                on `device_accounts`.`id` = `bannerables`.`bannerable_id`
                where `banners`.`id` = `bannerables`.`banner_id`
                and `bannerables`.`bannerable_type` = DeviceAccount
                and `device_accounts`.`id` = 4
            ) or (
                exists (
                    select *
                    from `stores`
                    inner join `bannerables`
                    on `stores`.`id` = `bannerables`.`bannerable_id`
                    where `banners`.`id` = `bannerables`.`banner_id`
                    and `bannerables`.`bannerable_type` = Store
                    and `stores`.`id` = 1
                )
            )
            order by `priority` desc | 17ms
LOG;
    }
}
